﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Viettel.VOFFICE.DAO.Models;
using Viettel.VOFFICE.Web.Helpers;
using Viettel.VOFFICE.Web.Models;

namespace Viettel.VOFFICE.Web.Controllers
{
    public class ManageActionNameController : BaseController
    {
        #region Controller Action
        [HttpGet]
        [ActionName("get_actionnames")]
        public JsonResult GetAllActionName(string controllerName)
        {
            var types =
                from a in AppDomain.CurrentDomain.GetAssemblies()
                from t in a.GetTypes()
                where typeof(IController).IsAssignableFrom(t) &&
                        string.Equals(controllerName + "Controller", t.Name, StringComparison.OrdinalIgnoreCase)
                select t;

            var controllerType = types.FirstOrDefault();

            if (controllerType == null)
            {
                return Json(SimplyResponse.Response500());
            }
            return Json(
                new JsonResponse()
                    {
                        Status = true,
                        Result = new ReflectedControllerDescriptor(controllerType)
                            .GetCanonicalActions().Select(x => x.ActionName)
                            .ToList()
                    }, JsonRequestBehavior.AllowGet);
        }
        [HttpPost]
        [ActionName("build_controller_tree")]
        public JsonResult GetControllerTree()
        {
            var controllerList = new TreeviewModel
            {
                attr = new TreeviewAttr() { id = "" },
                id = "",
                data = @Resources.Resources.ManageActionName_TreeRootNode,
                children = new List<TreeviewModel>()
            };
            foreach (var type in MvcHelper.GetSubClasses<Controller>())
            {
                if (GetAttrHelper.Get(type) != "")
                {
                    var newRoot = new TreeviewModel { attr = new TreeviewAttr(), id = type.Name, data = GetAttrHelper.Get(type) };
                    newRoot.attr.id = type.Name;
                    newRoot.attr.title = GetAttrHelper.Get(type);
                    newRoot.attr.selected = false;
                    newRoot.children = PopulateTree(type);
                    controllerList.children.Add(newRoot);
                }
            }
            return Json(controllerList);
        }

        private List<TreeviewModel> PopulateTree(Type tController)
        {
            var controllerList = new List<TreeviewModel>();
            foreach (var item in new ReflectedControllerDescriptor(tController)
                            .GetCanonicalActions())
            {
                var treeNode = new TreeviewModel
                                   {
                                       attr = new TreeviewAttr(),
                                       id = item.ActionName,
                                       data = GetAttrHelper.Get(tController, item.ActionName)
                                   };
                treeNode.attr.id = item.ActionName;
                treeNode.attr.title = GetAttrHelper.Get(tController, item.ActionName);
                treeNode.attr.selected = false;
                controllerList.Add(treeNode);
            }
            return controllerList;
        }
        #endregion

        #region System function

        [HttpGet]
        [ActionName("gets")]
        public JsonResult GetChildren(int id)
        {
            try
            {
                var rootNode = unitOfWork.SystemFunctionRepository.GetById(id);
                var listFunction = new List<SystemFunctionModel>();
                if (rootNode != null)
                {
                    var newModel = new SystemFunctionModel
                                       {
                                           Id = rootNode.Id,
                                           Name = rootNode.Name,
                                           ActionControllerName = rootNode.ActionControllerName,
                                           Description = rootNode.Description,
                                           IsActive = rootNode.IsActive != null && (bool)rootNode.IsActive,
                                           IsRoot = true
                                       };
                    listFunction.Add(newModel);
                    var listChildren = unitOfWork.SystemFunctionRepository.GetByParentId(rootNode.Id);
                    if (listChildren != null)
                    {
                        listFunction.AddRange(listChildren.Select(listChild => new SystemFunctionModel
                                                                                   {
                                                                                       Id = listChild.Id,
                                                                                       Name = listChild.Name,
                                                                                       ActionControllerName = listChild.ActionControllerName,
                                                                                       Description = listChild.Description,
                                                                                       IsActive = listChild.IsActive != null && (bool)listChild.IsActive,
                                                                                       IsRoot = false
                                                                                   }));
                    }
                }
                else
                {
                    var rootFunctions = unitOfWork.SystemFunctionRepository.GetRootFunction();
                    if (rootFunctions != null)
                    {
                        listFunction.AddRange(rootFunctions.Select(listChild => new SystemFunctionModel
                        {
                            Id = listChild.Id,
                            Name = listChild.Name,
                            ActionControllerName = listChild.ActionControllerName,
                            Description = listChild.Description,
                            IsActive = listChild.IsActive != null && (bool)listChild.IsActive,
                            IsRoot = false
                        }));
                    }
                }
                return Json(new JsonResponse()
                {
                    Status = true,
                    Result = listFunction
                }, JsonRequestBehavior.AllowGet);
            }
            catch (Exception)
            {
                return Json(SimplyResponse.Response500());
            }
        }
        [HttpGet]
        [ActionName("get")]
        public JsonResult GetById(int id)
        {
            try
            {
                var functionItem = unitOfWork.SystemFunctionRepository.GetById(id);
                if (functionItem != null)
                {
                    var returnFunction = new SystemFunctionModel
                    {
                        Id = functionItem.Id,
                        Name = functionItem.Name,
                        Description = functionItem.Description,
                        IsActive = functionItem.IsActive != null && (bool)functionItem.IsActive
                    };
                    return Json(new JsonResponse
                    {
                        Status = true,
                        Result = returnFunction
                    }, JsonRequestBehavior.AllowGet);
                }
                return Json(SimplyResponse.Response200());
            }
            catch (Exception)
            {
                return Json(SimplyResponse.Response500());
            }
        }
        [HttpPost]
        [ActionName("add")]
        public JsonResult AddFunction(SystemFunctionModel model)
        {
            try
            {
                List<ValidationResult> outError;
                if (!model.IsValid(out outError))
                {
                    return Json(new JsonResponse()
                    {
                        Status = false,
                        Result = string.Join(", ", outError.Select(o => o.ErrorMessage).ToArray())
                    });
                }
                var systemFunction = new v_SystemFunction
                {
                    Name = model.Name,
                    Description = model.Description,
                    ActionControllerName = model.ActionControllerName,
                    IsActive = model.IsActive,
                    ParentId = model.ParentId == 0 ? null : model.ParentId
                };
                unitOfWork.SystemFunctionRepository.Insert(systemFunction);
                return Json(SimplyResponse.ResposeWithId(systemFunction.Id));
            }
            catch (Exception exception)
            {
                return Json(SimplyResponse.Response500(exception.ToString()));
            }
        }
        [HttpPost]
        [ActionName("delete")]
        public JsonResult DeleteFunction(int curentid)
        {
            var children = unitOfWork.SystemFunctionRepository.GetByParentId(curentid);
            if (!children.Any())
            {
                var curentFunction = unitOfWork.SystemFunctionRepository.GetById(curentid);
                if (curentFunction != null)
                {
                    unitOfWork.SystemFunctionRepository.Delete(curentFunction);
                    return Json(SimplyResponse.Response200());
                }
            }

            return Json(SimplyResponse.Response500(Resources.Resources.SystemMenu_RecursiveData));
        }
        [HttpPut]
        [ActionName("update")]
        public JsonResult Update(SystemFunctionModel model, string modifiedscope)
        {
            try
            {
                var systemModel = unitOfWork.SystemFunctionRepository.GetById(model.Id);
                if (systemModel != null)
                {
                    if (modifiedscope.ToUpper() == "ISACTIVE")
                    {
                        systemModel.IsActive = model.IsActive;
                    }
                    else
                    {
                        systemModel.Name = model.Name;
                        systemModel.Description = model.Description;
                        systemModel.ActionControllerName = model.ActionControllerName;
                    }
                    unitOfWork.SystemFunctionRepository.Update(systemModel);
                }
                return Json(SimplyResponse.Response200());
            }
            catch (Exception)
            {
                return Json(SimplyResponse.Response500());
            }
        }

        #endregion

        #region Build System Function TreeView

        [HttpPost]
        [ActionName("get_function_treeview")]
        public JsonResult GetFunctionTreeView()
        {
            var systemFunctionTree = new SystemFunctionTreeView()
            {
                attr = new SystemFunctionAttribute() { id = 0 },
                id = 0,
                data = @Resources.Resources.ManageActionName_TreeRootNode
            };
            var rootFunctions = unitOfWork.SystemFunctionRepository.GetRootFunction();
            if (rootFunctions != null)
            {
                foreach (var item in rootFunctions)
                {
                    var newFunction = new SystemFunctionTreeView
                                          {
                                              attr = new SystemFunctionAttribute(),
                                              id = item.Id,
                                              data = item.Name
                                          };
                    newFunction.attr.id = item.Id;
                    newFunction.attr.title = item.Name;
                    newFunction.attr.rolelist = item.RolesName;
                    PopulateFunctionTreeView(item.Id, newFunction);
                    systemFunctionTree.children.Add(newFunction);
                }
            }
            return Json(systemFunctionTree);
        }

        private void PopulateFunctionTreeView(int rootPath, SystemFunctionTreeView rootNode)
        {
            if (rootNode.children == null)
            {
                rootNode.children = new List<SystemFunctionTreeView>();
            }
            var childNodes = unitOfWork.SystemFunctionRepository.GetByParentId(rootPath);
            if (childNodes == null) return;
            foreach (var childNode in childNodes)
            {
                var newNode = new SystemFunctionTreeView
                                  {
                                      attr = new SystemFunctionAttribute(),
                                      id = childNode.Id,
                                      data = childNode.Name
                                  };
                newNode.attr.id = childNode.Id;
                newNode.attr.title = childNode.Name;
                newNode.attr.rolelist = childNode.RolesName;
                PopulateFunctionTreeView(childNode.Id, newNode);
                rootNode.children.Add(newNode);
            }
        }
        #endregion
    }
}
